#ifndef utility_Time_h
#define utility_Time_h

#include "String.h"
#include <time.h>

namespace serika
{
	namespace ut
	{
		class Time : public tm
		{
		public:
			Time();
	#ifdef WIN32
			Time(__time32_t time, bool local = true);
			Time(__time64_t time, bool local = true);
	#else
			Time(time_t time, bool local = true);
	#endif
			Time(const Time& other);
			Time(const tm& other);
	
		public:
			static const Time& Now(bool local = true);
			static Time INVALID;
	
			bool IsValid() const { return *this != INVALID; }
	
			int GetSecond() const { return tm_sec; }	/* seconds after the minute - [0,59] */
			int GetMinute() const { return tm_min; }	/* minutes after the hour - [0,59] */
			int GetHour() const { return tm_hour; }		/* hours since midnight - [0,23] */
			int GetDay() const { return tm_mday; }		/* day of the month - [1,31] */
			int GetMonth() const { return tm_mon + 1; }		/* months since January - [0,11] */
			int GetYear() const { return tm_year + 1900; }	/* years in tm is since 1900 */
			int GetWeekDay() const { return tm_wday; }	/* days since Sunday - [0,6] */
			int GetYearDay() const { return tm_yday; }	/* days since January 1 - [0,365] */
			bool IsDST() const { return tm_isdst != 0; }	/* daylight savings time flag */
	
			void SetSecond(int sec) { tm_sec = sec; }	/* seconds after the minute - [0,59] */
			void SetMinute(int min) { tm_min = min; }	/* minutes after the hour - [0,59] */
			void SetHour(int hour) { tm_hour = hour; }		/* hours since midnight - [0,23] */
			void SetDay(int day) { tm_mday = day; }		/* day of the month - [1,31] */
			void SetMonth(int month) { tm_mon = month - 1; }		/* months since January - [0,11] */
			void SetYear(int year) { tm_year = year - 1900; }	/* years in tm is since 1900 */
			void SetWeekDay(int wday) { tm_wday = wday; }	/* days since Sunday - [0,6] */
			void SetYearDay(int yday) { tm_yday = yday; }	/* days since January 1 - [0,365] */
			void SetDST(bool dst) { tm_isdst = dst ? 1 : 0; }	/* daylight savings time flag */
	
			time_t ToTimeT() const;
			String ToString(const Char*format = _T("%Y-%m-%d %H:%M:%S")) const;
			bool Parse(const Char* datetime, const Char* format = _T("%Y-%m-%d %H:%M:%S"));
			bool ParseDate(const Char* date, const Char* format = _T("%Y-%m-%d"));
			bool ParseTime(const Char* time, const Char* format = _T("%H:%M:%S"));
	
			static const Time& FromString(const Char* datetime, const Char* format = _T("%Y-%m-%d %H:%M:%S"));
			static const Time& FromDateString(const Char* date, const Char* format = _T("%Y-%m-%d"));
			static const Time& FromTimeString(const Char* time, const Char* format = _T("%H:%M:%S"));
	
			bool operator == (const Time& other) const;
			bool operator != (const Time& other) const;
			bool operator > (const Time& other) const;
			bool operator < (const Time& other) const;
			bool operator >= (const Time& other) const;
			bool operator <= (const Time& other) const;
			Time& operator = (const Time& other);
			Time& operator = (const tm& other);
	
			int CompareDay(const Time& other) const;
	
		private:
			int ParseNumber(const Char* s, size_t len, size_t digits) const;
		};
	}
}
	
#endif
